package controller

import (
	"fmt"
	"hello/src/code/007gin_project/web/model"
	"hello/src/code/007gin_project/web/utils"
	"image/png"
	"net/http"
	"os"
	"path"
	"strings"

	"github.com/afocus/captcha"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
)

// 用户模块

// 获取session信息服务
func GetSesion(ctx *gin.Context) {
	// 1. 初始化错误返回的map
	var Data struct {
		Name string `json:"name"`
	}
	var NewResponse = make(map[string]interface{})
	s := sessions.Default(ctx)
	userName := s.Get("userName")
	if userName != nil {
		Data.Name = userName.(string)
		NewResponse = JsonCommonResponse(utils.RECODE_OK, Data)
	} else {
		NewResponse = JsonCommonResponse(utils.RECODE_SESSIONERR, nil)
	}
	// 2. 返回json格式
	ctx.JSON(http.StatusOK, NewResponse)
}

// 获取验证码图片服务
func GetImageCd(ctx *gin.Context) {
	// 1. 获取前端传的uuid值
	imageUuid := ctx.Param("uuid")
	fmt.Println("uuid: ", imageUuid)

	// 2. 使用afocus图片验证码生成器生成随机的4位验证码
	cap := captcha.New()
	// 设置字体、验证码大小、干扰强度
	cap.SetFont("./conf/comic.ttf")
	cap.SetSize(128, 64)
	cap.SetDisturbance(captcha.MEDIUM)
	// 创建验证码，captcha.NUM表示字符模式数字类型
	// 返回 验证码图像对象 、验证码字符串
	// 后期可以对字符串进行对比以及判断验证
	img, _ := cap.Create(4, captcha.NUM)
	png.Encode(ctx.Writer, img)
}

// 处理session
func PostLogin(ctx *gin.Context) {
	// 1. 获取前端传参
	var loginData struct {
		Mobile   string `json:"mobile"`
		Password string `json:"password"`
	}
	ctx.Bind(&loginData)

	// 2. 处理数据
	var NewResponse = make(map[string]interface{})
	userName, err := model.LoginSession(loginData.Mobile, loginData.Password)
	if err == nil {
		// 登陆成功
		NewResponse = JsonCommonResponse(utils.RECODE_OK, nil)
		// 将登陆状态保存到session中
		s := sessions.Default(ctx)
		s.Set("userName", userName)
		s.Save()
	} else {
		// 登陆失败
		NewResponse = JsonCommonResponse(utils.RECODE_LOGINERR, nil)
	}

	// 3. 写入数据
	ctx.JSON(http.StatusOK, NewResponse)
}

// 退出
func DeleteSession(ctx *gin.Context) {
	// 1. 清除session
	s := sessions.Default(ctx)
	s.Delete("userName")
	var NewResponse = make(map[string]interface{})
	if err := s.Save(); err != nil {
		NewResponse = JsonCommonResponse(utils.RECODE_UNKNOWERR, nil)
	} else {
		NewResponse = JsonCommonResponse(utils.RECODE_OK, nil)
	}

	// 2. 返回信息
	ctx.JSON(http.StatusOK, NewResponse)
}

// 获取用户基本信息
func GetUserInfo(ctx *gin.Context) {
	// 1. 获取session
	s := sessions.Default(ctx)
	userName := s.Get("userName")
	var resp = make(map[string]interface{})
	defer ctx.JSON(http.StatusOK, resp)

	// 2. 访问数据库, 返回用户信息
	user, err := model.GetUserInfo(userName.(string))
	if err != nil {
		// 查询失败
		OperateCommonResp(resp, utils.RECODE_DBERR, nil)
		return
	}

	// 3. 组装数据
	temp := make(map[string]interface{})
	temp["user_id"] = user.ID
	temp["name"] = user.Name
	temp["mobile"] = user.Mobile
	temp["real_name"] = user.Real_name
	temp["id_card"] = user.Id_card
	temp["avatar_url"] = user.Avatar_url
	OperateCommonResp(resp, utils.RECODE_OK, temp)
}

// 更新用户信息
func PutUserInfo(ctx *gin.Context) {
	// 1. 获取session
	s := sessions.Default(ctx)
	userName := s.Get("userName")
	var resp = make(map[string]interface{})
	defer ctx.JSON(http.StatusOK, resp)

	var NewNameData struct {
		Name string `json:"name"`
	}
	ctx.Bind(&NewNameData)
	// 2. 更新用户信息(数据库)
	if err := model.UpdateUserInfo(userName.(string), NewNameData.Name, ""); err != nil {
		OperateCommonResp(resp, utils.RECODE_DBERR, nil)
		return
	}
	// 3. 成功
	OperateCommonResp(resp, utils.RECODE_OK, NewNameData)

	// 4. 更新用户信息(session)
	s.Set("userName", NewNameData.Name)
	s.Save()
}

// 上传用户头像
func PostAvatar(ctx *gin.Context) {
	// 1. 单文件
	file, _ := ctx.FormFile("file")

	var resp = make(map[string]interface{})
	defer ctx.JSON(http.StatusOK, resp)

	// 2. 限制文件上传类型
	fileExt := strings.ToLower(path.Ext(file.Filename))
	if fileExt != ".png" && fileExt != ".jpg" && fileExt != ".gif" && fileExt != ".jpeg" {
		OperateCommonResp(resp, utils.RECODE_PARAMERR, nil)
		return
	}

	// 3. 上传文件到指定的路径
	if err := ctx.SaveUploadedFile(file, "conf/"+file.Filename); err != nil {
		OperateCommonResp(resp, utils.RECODE_IOERR, nil)
		return
	}

	// 4. 先传到本地(获取文件路径) -> 再上传头像到七牛云服务器 -> 删除本地文件
	RealStr, _ := os.Getwd()
	QiniuFilepath := RealStr + "/conf/" + file.Filename
	utils.UploadImage(QiniuFilepath, file.Filename)
	os.Remove(QiniuFilepath)

	// 5. 更改数据库中用户头像数据
	s := sessions.Default(ctx)
	userName := s.Get("userName")
	if err := model.UpdateUserInfo(userName.(string), "", utils.QiniuUrl+file.Filename); err != nil {
		OperateCommonResp(resp, utils.RECODE_DBERR, nil)
		return
	}

	// 6. 成功
	OperateCommonResp(resp, utils.RECODE_OK, nil)
}
